package dao;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import parsers.CommonMethods;
import parsers.student.DepartmentsParser;
import parsers.student.DirectionsParser;
import parsers.student.GroupParser;

import model.student.Department;
import model.student.Direction;
import model.student.Group;

public class StudentDAO 
{
	private static Map<String, Department> departmentsCP = new HashMap<String, Department>();
	private static Map<String, Direction> directionsCP = new HashMap<String, Direction>();
	private static Map<String, Group> groupsCP = new HashMap<String, Group>();
	
	private static String currentDate = util.Utilities.getDateTime();
	
	private static String[] file = new String[] {makeFileName("depCP"), makeFileName("dirCP"), makeFileName("groCP")};
	
	private long startTime;
	
	@SuppressWarnings("unchecked")
	public StudentDAO()
	{
		startTime();
		System.out.print("Initialising Student->Departments: ");
		if( (new File(file[0])).exists() )
		{
			System.out.print("(find serialized file " + file[0] + ") ");
			departmentsCP = (Map<String, Department>) util.Utilities.deserialize(file[0]);
		}
		else
		{
			initDepartments();
			
		}
		System.out.println(countTime() + " ms");
		
		/////////////////////////////////////////////
		
		startTime();
		System.out.print("Initialising Student->Groups: ");
		if( (new File(file[1])).exists() )
		{
			System.out.print("(find serialized file " + file[1] + ") ");
			directionsCP = (Map<String, Direction>) util.Utilities.deserialize(file[1]);
		}
		else
		{
			initGroups();
		}
		System.out.println(countTime() + " ms");
		
		/////////////////////////////////////////////
		
		startTime();
		System.out.print("Initialising Student->GroupsSchedule: ");
		if( (new File(file[2])).exists() )
		{
			System.out.print("(find serialized file " + file[2] + ") ");
			groupsCP = (Map<String, Group>) util.Utilities.deserialize(file[2]);
		}
		else
		{
			initGroupsSchedule();
		}
		System.out.println(countTime() + " ms");
	}
	
	private static String makeFileName(String name)
	{
		return Linker.path + StudentDAO.class.getName() + name + currentDate + ".jsr";
	}
	
	public static void serialize()
	{
		if( !(new File(file[0])).exists() )
		{
			util.Utilities.serialize(departmentsCP, file[0]);
		}
		
		if( !(new File(file[1])).exists() )
		{
			util.Utilities.serialize(directionsCP, file[1]);
		}
		
		if( !(new File(file[2])).exists() )
		{
			util.Utilities.serialize(groupsCP, file[2]);
		}
	}
	
	private void initDepartments()
	{
		DepartmentsParser dp = new DepartmentsParser();
		ArrayList<Department> departments = null;
		
		try
		{
			departments = dp.parse(new URL("http://plan.uz.zgora.pl/grupy_lista_kierunkow.php"));
			
			for (int i = 0; i < departments.size(); i++)
			{
				departmentsCP.put(departments.get(i).getId(), departments.get(i));
			}
		} 
		catch (MalformedURLException e)
		{
			e.printStackTrace();
		} 
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	private void initGroups()
	{
		Iterator<Department> departments = departmentsCP.values().iterator();
		while(departments.hasNext())
		{
			Department department = departments.next();
			ArrayList<Direction> directions = department.getDirections();
			for (int i = 0; i < directions.size(); i++)
			{
				Direction direction = new Direction(directions.get(i).getName());
				direction.setId(directions.get(i).getId());
				direction.setLink(CommonMethods.parseLink(directions.get(i).getLink()));
				
				DirectionsParser dp = new DirectionsParser(direction);
				try
				{
					dp.parse(true);
					directionsCP.put(direction.getId(), direction);
				} 
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
		}
	}
	
	private void initGroupsSchedule()
	{
		Iterator<Direction> directions = directionsCP.values().iterator();
		while(directions.hasNext())
		{
			Direction direction = directions.next();
			ArrayList<Group> groups = direction.getGroups();
			for (int i = 0; i < groups.size(); i++)
			{
				Group group = new Group(groups.get(i).getName(), groups.get(i).getDescription());
				group.setId(groups.get(i).getId());
				group.setLink(CommonMethods.parseLink(groups.get(i).getLink()));
				
				GroupParser gp = new GroupParser(group);
				try
				{
					gp.parse(true);
					groupsCP.put(group.getId(), group);
				} 
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
		}
	}

	public static Map<String, Department> getDepartmentsCP()
	{
		return departmentsCP;
	}

	public static Map<String, Direction> getDirectionsCP()
	{
		return directionsCP;
	}

	public static Map<String, Group> getGroupsCP()
	{
		return groupsCP;
	}

	private void startTime()
	{
		startTime = System.currentTimeMillis();
	}
	
	private long countTime()
	{
		return System.currentTimeMillis() - startTime;
	}
}